﻿using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;
using System.Collections.Generic;

namespace StockholmsStad.Data.Interfaces
{
    /// <summary>
    /// Hantering av användare i systemet
    /// </summary>
    public interface IUserAgent
    {
        /// <summary>
        /// Skapar en ny användare
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="userRoleId"></param>
        /// <returns></returns>
        int CreateUser(IDataContext context, string username, string password, int userRoleId);

        /// <summary>
        /// Skapar en ny användare i parvis-applikationen. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="parvisUser">Den användare som ska läggas till (<see cref="ParvisUser"/>).</param>
        /// <param name="password"></param>
        /// <returns>Id-numret på den skapade användaren. </returns>
        int AddUser(IDataContext context, ParvisUser parvisUser, string password);

        /// <summary>
        /// Uppdaterar en användare i parvis-applikationen. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="parvisUser">Den användare som ska uppdateras(<see cref="ParvisUser"/>).</param>
        /// <returns>Id-numret på den skapade användaren. </returns>
        void UpdateUser(IDataContext context, ParvisUser parvisUser);

        /// <summary>
        /// Hämtar en (aktiv) användare utifrån användarnamnet
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="username"></param>
        /// <returns></returns>
        User GetUser(IDataContext context, string username);

        /// <summary>
        /// Hämtar alla användare som inte har rollen kund
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="includeInactiveUsers">Inkludera även inaktiva användare.</param>
        /// <returns>En lista med alla användare.</returns>
        List<ParvisUser> GetUsers(IDataContext context, bool includeInactiveUsers);

        /// <summary>
        /// Hämtar en befintlig användare
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="parvisUserId">Användarens unika nyckel.</param>
        /// <returns>Användaren (<see cref="ParvisUser"/>).</returns>
        ParvisUser GetParvisUser(IDataContext context, int parvisUserId);

        ///<summary>
        /// Kontrollerar att användaren får logga in på webben
        ///</summary>
        ///<param name="context">Det databascontext som operationen köra i</param>
        ///<param name="username"></param>
        ///<param name="password"></param>
        ///<returns></returns>
        bool IsValidWebUser(IDataContext context, string username, string password);

        ///<summary>
        /// Uppdaterar användarnamnet för user
        ///</summary>
        ///<param name="context">Det databascontext som operationen köra i</param>
        ///<param name="coupleId">Hitta user med hjälp av coupleId</param>
        ///<param name="username"></param>
        void UpdateUser(IDataContext context, int coupleId, string username);

        /// <summary>
        /// Tar bort en användare
        /// </summary>
        /// <param name="context"></param>
        /// <param name="userId"></param>
        void DeleteUser(IDataContext context, int userId);

        /// <summary>
        /// Tar bort en parvis användare
        /// </summary>
        /// <param name="context"></param>
        /// <param name="userId"></param>
        void DeleteParvisUser(IDataContext context, int userId);

        /// <summary>
        /// Returnerar true om användarnamnet är unikt
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="username"></param>
        /// <returns></returns>
        bool IsUserNameUnique(IDataContext context, string username);

        /// <summary>
        /// Genererar ett nytt slumpat lösenord
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        string CreatePassword(IDataContext context);

        ///<summary>
        /// Skicka mail med lösenord till användaren
        ///</summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        ///<param name="user">Vilken person som ska ha uppgifterna</param>
        void SendForgottenPasswordMail(IDataContext context, ParvisUser user);

        ///<summary>
        /// Skicka mail med lösenord till användaren
        ///</summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        ///<param name="person">Vilken person som ska ha uppgifterna</param>
        ///<param name="user">Användaruppgifterna</param>
        void SendForgottenPasswordMail(IDataContext context, PersonDetails person, User user);

        /// <summary>
        /// Skapar en ny användare i systemet. Kan endast göras utav systemadministratör och användaren
        /// får endast vara systemadministratör, moderator eller läsbehörig (inte kund). När användaren
        /// har lagts till så mailas lösenordet ut till personen ifråga.
        /// </summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        /// <param name="username">Användarnamnet på användaren. </param>
        /// <param name="userRoleId">Den behörighet användaren ska få. </param>
        void AddUser(IDataContext context, string username, int userRoleId);
 
        /// <summary>
        /// Autentisering av användare mot systemet. 
        /// </summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        /// <param name="user">Den användare som vill försöka logga in. </param>
        /// <returns>Behörig användare med dess roll, annars null. </returns>
        User Login(IDataContext context, User user);
 
        /// <summary>
        /// Avaktiverar en användare i systemet. 
        /// </summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        /// <param name="username">Användarnamnet på den person som ska avaktiveras. </param>
        void SetUserInactive(IDataContext context, string username);

        /// <summary>
        /// Hämtar alla användarrollen (förutom kund-rollen). 
        /// </summary>
        ///<param name="context">Det databascontext som operationen kör i. </param>
        /// <param name="excludeRoles">Exkludera vissa användartyper. </param>
        /// <returns>En lista med alla roller. </returns>
        List<UserRole> GetRoles(IDataContext context, List<UserRole> excludeRoles);

        /// <summary>
        /// Ändrar en användare
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="ticketId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        void ChangeUser(IDataContext context, int ticketId, int? userId);
    }
}